package com.example.composelauncher;

import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Handler;

import androidx.annotation.NonNull;
import androidx.hilt.lifecycle.ViewModelInject;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import java.util.ArrayList;
import java.util.List;

import dagger.hilt.android.qualifiers.ApplicationContext;

public class LauncherViewModel extends ViewModel {

    private final MutableLiveData<List<AppIcon>> _appIconList = new MutableLiveData<>();
    public final LiveData<List<AppIcon>> appIconList = _appIconList;

    private final MutableLiveData<Boolean> _allAppLoading = new MutableLiveData<>(true);
    public final LiveData<Boolean> allAppLoading = _allAppLoading;

    @SuppressLint("StaticFieldLeak")
    private Context context;
    private boolean firstTime = true;
    private final int appIconSize;
    private final Canvas canvas;
    private final Handler mDirtyWorker = new Handler();
    private final Runnable mAppLoadTask = new Runnable() {
        @Override
        public void run() {
            onAppDataDirty();
        }
    };

    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO:这儿正确逻辑应该是根据PackageManager传来的包名做diff更新
            mDirtyWorker.removeCallbacks(mAppLoadTask);
            mDirtyWorker.postDelayed(mAppLoadTask, 1000);
        }
    };

    @ViewModelInject
    LauncherViewModel(@ApplicationContext Context context) {
        this.context = context;
        appIconSize = context.getResources().getDimensionPixelSize(R.dimen.app_icon_size);
        canvas = new Canvas();

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        this.context.registerReceiver(receiver, filter);

        mDirtyWorker.post(mAppLoadTask);

    }

    @SuppressLint("StaticFieldLeak")
    void onAppDataDirty() {
        new AsyncTask<Context, Void, List<AppIcon>>() {

            @Override
            protected void onPreExecute() {
                _allAppLoading.setValue(firstTime);
                firstTime = false;
            }

            @Override
            protected List<AppIcon> doInBackground(Context... contexts) {
                PackageManager packageManager = contexts[0].getPackageManager();
                List<ResolveInfo> resolveInfos =
                        packageManager.queryIntentActivities(Intent.makeMainActivity(null), 0);
                ArrayList<AppIcon> appIconResult = new ArrayList<>();
                resolveInfos.forEach(resolveInfo -> {
                    AppIcon appIcon = mapResolveInfo2AppIcon(contexts[0], resolveInfo);
                    if (appIcon != null) {
                        appIconResult.add(appIcon);
                    }
                });
                return appIconResult;
            }

            private AppIcon mapResolveInfo2AppIcon(Context context, ResolveInfo info) {
                if (info == null || info.activityInfo == null
                        || info.activityInfo.packageName.equals(context.getPackageName())) {
                    return null;
                }
                String title = info.activityInfo.loadLabel(context.getPackageManager()).toString();
                Drawable drawable = info.activityInfo.loadIcon(context.getPackageManager());

                Intent intent = Intent.makeMainActivity(ComponentName
                        .createRelative(info.activityInfo.packageName, info.activityInfo.name));

                Bitmap bitmap = Bitmap.createBitmap(appIconSize, appIconSize, Bitmap.Config.ARGB_8888);
                canvas.setBitmap(bitmap);
                drawable.setBounds(0, 0, appIconSize, appIconSize);
                drawable.draw(canvas);
                canvas.setBitmap(null);

                return new AppIcon(title, bitmap, intent);
            }

            @Override
            protected void onPostExecute(List<AppIcon> appIcons) {
                _allAppLoading.setValue(false);
//                ArrayList<AppIcon> multiList = new ArrayList<>();
//                multiList.addAll(appIcons);
//                for (int i = 1; i < 2; i++) {
//                    for (int j = 0; j < appIcons.size(); j++) {
//                        AppIcon icon = appIcons.get(j);
//                        multiList.add(icon.copy(icon.getTitle() + "_copy", icon.getIcon(), icon.getIntent()));
//                    }
//                }
//                _appIconList.setValue(multiList);
                _appIconList.setValue(appIcons);
                firstTime = false;
            }
        }.execute(context);
    }

    public void onAppReorder(@NonNull List<AppIcon> userReorder) {
        // TODO：本地持久化记录着新的顺序的app列表
        _appIconList.setValue(userReorder);
    }

    public void onAppIconClicked(@NonNull AppIcon appIcon) {
        Intent intent = new Intent(appIcon.getIntent());
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
            context.startActivity(intent);
        } catch (ActivityNotFoundException exception) {
            exception.printStackTrace();
        }
    }

    @Override
    protected void onCleared() {
        super.onCleared();
        mDirtyWorker.removeCallbacks(mAppLoadTask);
        this.context.unregisterReceiver(receiver);
        this.context = null;
    }
}
